home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-08 | 8.1 KB | 321 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: FWFxMath.cpp
- // Release Version: $ 1.0d11 $
- //
- // Copyright: © 1993, 1995 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWOS.hpp"
-
- #ifndef FWFXMATH_H
- #include "FWFxMath.h"
- #endif
-
- #ifndef FWSTREAM_H
- #include "FWStream.h"
- #endif
-
- #ifdef FW_DEBUG
- #include <stdio.h>
- #endif
-
- //========================================================================================
- // RunTime Info
- //========================================================================================
-
- #if FW_LIB_EXPORT_PRAGMAS
- #pragma lib_export on
- #endif
-
- #ifdef FW_BUILD_MAC
- #pragma segment FWODUtil_FixedMath
- #endif
-
- //========================================================================================
- // CLASS FW_CFixed
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_CFixed::Sin
- //----------------------------------------------------------------------------------------
-
- FW_CFixed FW_CFixed::Sin() const
- {
- ODFract fract = ODFractSinCos(fRep, NULL);
- return FW_CFixed(fract >> 14);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CFixed::Cos
- //----------------------------------------------------------------------------------------
-
- FW_CFixed FW_CFixed::Cos() const
- {
- ODFract frac;
- ODFractSinCos(fRep, &frac);
- return FW_CFixed(frac >> 14);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CFixed::Sqrt
- //----------------------------------------------------------------------------------------
-
- FW_CFixed FW_CFixed::Sqrt() const
- {
- ODWide wide;
- wide.hi = 0;
- wide.lo = fRep;
- ODWideShift(&wide, -16);
-
- ODFixed fixed = ODWideSquareRoot(&wide);
- return FW_CFixed(fixed);
- }
-
- //========================================================================================
- // CLASS FW_CWide
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_IntToWide
- //----------------------------------------------------------------------------------------
-
- FW_CWide FW_FUNC_ATTR FW_IntToWide(int i)
- {
- return FW_CWide(i, 0);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_ODFixedToWide
- //----------------------------------------------------------------------------------------
-
- FW_CWide FW_FUNC_ATTR FW_ODFixedToWide(ODFixed f)
- {
- ODWide wide;
- wide.hi = 0;
- wide.lo = f;
- ODWideShift(&wide, -16);
- return FW_CWide(wide);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CWide::FW_CWide
- //----------------------------------------------------------------------------------------
-
- FW_CWide::FW_CWide(FW_CFixed f)
- {
- fRep.hi = 0;
- fRep.lo = f.AsODFixed();
- ODWideShift(&fRep, -16);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CWide::AsInt
- //----------------------------------------------------------------------------------------
-
- int FW_CWide::AsInt() const
- {
- // Rounding
- ODWide wide = fRep;
- ODWide half;
- half.hi = 0;
- half.lo = 0x80000000l;
- ODWideAdd(&wide, &half);
-
- return wide.hi;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CWide::AsODFixed
- //----------------------------------------------------------------------------------------
-
- ODFixed FW_CWide::AsODFixed() const
- {
- ODWide wide = fRep;
-
- // Rounding
- ODWide half;
- half.hi = 0;
- half.lo = 0x00008000l;
- ODWideAdd(&wide, &half);
-
- if(wide.hi > 0x7FFF)
- return 0x7FFFFFFFl;
-
- if(wide.lo < 0x8000)
- return 0x80000000l;
-
- return (wide.hi << 16) | (wide.lo >> 16);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CWide::operator FW_CFixed
- //----------------------------------------------------------------------------------------
-
- FW_CWide::operator FW_CFixed() const
- {
- return FW_ODFixedToFixed(AsODFixed());
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CWide::operator +
- //----------------------------------------------------------------------------------------
-
- FW_CWide FW_FUNC_ATTR operator + (const FW_CWide& w1, const FW_CWide& w2)
- {
- ODWide w = w1.fRep;
- ODWideAdd(&w, &w2.fRep);
- return FW_CWide(w);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CWide::operator -
- //----------------------------------------------------------------------------------------
-
- FW_CWide FW_FUNC_ATTR operator - (const FW_CWide& w1, const FW_CWide& w2)
- {
- ODWide w = w1.fRep;
- ODWideSubtract(&w, &w2.fRep);
- return FW_CWide(w);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_WideMultiply
- //----------------------------------------------------------------------------------------
-
- FW_CWide FW_FUNC_ATTR FW_WideMultiply (FW_CFixed f1, FW_CFixed f2)
- {
- ODWide w;
- ODWideMultiply(f1.fRep, f2.fRep, &w);
- return FW_CWide(w);
- }
-
- //----------------------------------------------------------------------------------------
- // operator /
- //----------------------------------------------------------------------------------------
-
- FW_CFixed FW_FUNC_ATTR operator / (const FW_CWide& w1, FW_CFixed f2)
- {
- return FW_CFixed(ODWideDivide(&w1.fRep, f2.fRep, NULL));
- }
-
- //========================================================================================
- // Global operators << and >>
- //========================================================================================
-
- FW_FUNC_ATTR const FW_CWritableStream& operator<<(const FW_CWritableStream& stream, const FW_CFixed& fx)
- {
- return stream << fx.fRep;
- }
-
- FW_FUNC_ATTR const FW_CReadableStream& operator>>(const FW_CReadableStream& stream, FW_CFixed& fx)
- {
- return stream >> fx.fRep;
- }
-
- #ifdef FW_DEBUG
-
- //========================================================================================
- // Debug versions of math operators
- //========================================================================================
-
- static void FixedError(FW_CFixed f1, FW_CFixed f2, const char* lpsz)
- {
- char buf[250];
- sprintf(buf, "Fixed error: %s, %.2f, %.2f", lpsz, f1.AsDouble(), f2.AsDouble());
- FW_DEBUG_MESSAGE(buf);
- }
-
- FW_FUNC_ATTR
- FW_CFixed operator+(FW_CFixed f1, FW_CFixed f2)
- {
- long rep1 = f1.fRep;
- long rep2 = f2.fRep;
-
- long repr = (rep1 >> 16) + (rep2 >> 16);
-
- if (repr < -32768 || repr > 32767)
- FixedError(f1, f2, "Add oflw");
-
- return FW_CFixed(f1.fRep + f2.fRep);
- }
-
- FW_FUNC_ATTR
- FW_CFixed operator-(FW_CFixed f1, FW_CFixed f2)
- {
- long rep1 = f1.fRep;
- long rep2 = f2.fRep;
-
- long repr = (rep1 >> 16) - (rep2 >> 16);
-
- if (repr < -32768 || repr > 32767)
- FixedError(f1, f2, "Sub oflw");
-
- return FW_CFixed(f1.fRep - f2.fRep);
- }
-
- FW_FUNC_ATTR
- FW_CFixed operator*(FW_CFixed f1, FW_CFixed f2)
- {
- long rep1 = f1.fRep;
- long rep2 = f2.fRep;
-
- long repr = (rep1 >> 16) * (rep2 >> 16);
-
- if (repr < -32768 || repr > 32767)
- FixedError(f1, f2, "Mul oflw");
-
- return FW_CFixed(ODFixedMultiply(f1.fRep, f2.fRep));
- }
-
- FW_FUNC_ATTR
- FW_CFixed operator/(FW_CFixed f1, FW_CFixed f2)
- {
- if (f2.fRep == 0)
- FixedError(f1, f2, "Div by 0");
-
- return FW_CFixed(ODFixedDivide(f1.fRep, f2.fRep));
- }
-
- #endif
-
- #ifdef FW_BUILD_WIN
- // [KVV] OpenDoc DR2 for Windows is missing the following routines
-
- #include <math.h>
-
- FW_FUNC_ATTR
- ODFract ODFractSinCos(ODFixed angle, ODFract *cosResult)
- {
- double flAngle = ODFixedToFloat(angle);
-
- double flSin = sin(flAngle);
- double flCos = cos(flAngle);
-
- ODFixed fxSin = ODFloatToFixed(flSin);
- ODFixed fxCos = ODFloatToFixed(flCos);
-
- if(cosResult != NULL)
- *cosResult = ODFixedToFract(fxCos);
-
- return ODFixedToFract(fxSin);
- }
-
- FW_FUNC_ATTR
- ODULong ODWideSquareRoot(const ODWide *src)
- {
- if(src->hi == 0 && src->lo == 0)
- return 0;
-
- if(src->hi < 0)
- return 0x7FFFFFFFl;
-
- double d = src->hi + src->lo / 4294967296.0;
- double s = sqrt(d);
-
- return ODFloatToFixed(s);
- }
-
- #endif
-